import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.JPanel;

import com.sun.opengl.util.FPSAnimator;

/**
 * 
 */

/**
 * @author ThienTN
 *
 */
public class MainCanvas  extends JPanel implements KeyListener,GLEventListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	final FPSAnimator animator;
	public GLU glu;
	public static GL gl;
	private GLCanvas canvas;
	
	public GameState 		gameState;
//	public Game_Menu 		gameMenu;
//	public Game_Playing		gamePlaying;
//	public Game_LevelState	gameLevelState;
	
	public Object[] SaveGame = new Object[30];
	public MainCanvas() {
		GLCapabilities caps = new GLCapabilities();
		caps.setSampleBuffers(true);
		caps.setNumSamples(4);

		glu = new GLU();
		canvas = new GLCanvas(caps);
		this.setLayout(new BorderLayout());
		this.add(canvas, BorderLayout.CENTER);
		
		// Set game state
		//SaveGame = new ArrayList<Object>();

		// Add event listener to canvas
		canvas.addGLEventListener(this);
		canvas.addKeyListener(this);
		canvas.setFocusable(true);
		canvas.requestFocus();
		
		animator = new FPSAnimator(canvas, GameDefine.REFRESH_FPS, true);
	}

	@Override
	public void keyPressed(KeyEvent arg0) {

		gameState.KeyPressed(arg0);
	}

	@Override
	public void keyReleased(KeyEvent arg0) {

		gameState.KeyReleased(arg0);
	}

	@Override
	public void keyTyped(KeyEvent arg0) {

		
	}

	@Override
	public void display(GLAutoDrawable arg0) {

		gameState.Update();
		UpdateCamera();
		gameState.Display(gl);
	}

	@Override
	public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init(GLAutoDrawable drawable) {
		// TODO Auto-generated method stub
		gl = drawable.getGL();
	    // Enable smooth shading, which blends colors nicely across a polygon, and
	    // smoothes out lighting.
	    gl.glShadeModel(GL.GL_SMOOTH);
	    
	    // Set background color (in RGBA). Alpha of 0 for total transparency
	    gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	    
	    // Setup the depth buffer & enable the depth testing
	    gl.glClearDepth(1.0f);
	    gl.glEnable(GL.GL_DEPTH_TEST);
	    gl.glDepthFunc(GL.GL_LEQUAL);
	    
	    // Best perspective correction
	    gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
		
	    // Set filter for texture
		gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
		gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
		gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
		gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
		
		// Set alpha blend for texture
		gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
		gl.glEnable(GL.GL_BLEND);
		
//		gameMenu 		= new Game_Menu(this);
//		gamePlaying		= new Game_Playing(this);
//		gameLevelState	= new Game_LevelState(this);
//		
//		gameState 	= gameMenu;
//		gameMenu.InitVar();
//		
//		gameMenu.LoadResources();
//		gamePlaying.LoadResources();
//		gameLevelState.LoadResources();
		
		gameState.LoadGame();
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int width,
			int height) {

		GameDefine.Width 	= width;
		GameDefine.Height	= height;
	    UpdateCamera();
	}

	public void UpdateCamera()
	{
		 // Set viewport
	    gl.glViewport(0, 0, GameDefine.Width, GameDefine.Height);
	    
		// 
	    gl.glMatrixMode(GL.GL_PROJECTION);
	    gl.glLoadIdentity();
	    
	     // Set projector & camera
	    glu.gluPerspective(45.0, (float)GameDefine.WINDOW_WIDTH / GameDefine.WINDOW_HEIGHT, 1, 100);
	    
	    glu.gluLookAt(GameDefine.eyeX, 	  GameDefine.eyeY,    GameDefine.eyeZ, 
	    			  GameDefine.centerX, GameDefine.centerY, GameDefine.centerZ, 
	    			  GameDefine.upX,     GameDefine.upY,     GameDefine.upZ);
	    
	    // Enable the model-view transform
	    gl.glMatrixMode(GL.GL_MODELVIEW);
	    gl.glLoadIdentity(); // reset
	}
}
